package com.wan37.logic.handler.message;

import com.wan37.logic.component.LogicWorkerHandlerCenter;
import com.wan37.logic.component.Worker;
import com.wan37.logic.domain.vo.MessageVO;
import com.wan37.logic.domain.vo.RoleVO;
import com.wan37.logic.domain.vo.UserVO;
import com.wan37.logic.global.HandlerManager;
import com.wan37.logic.global.reference.SpringContextHolder;
import com.wan37.logic.handler.MsgHandler;
import com.wan37.logic.handler.server.AutoAddHpHandler;
import com.wan37.logic.handler.server.DestroySceneHandler;
import com.wan37.logic.service.cache.RoleServiceCache;
import com.wan37.logic.service.cache.SceneServiceCache;
import com.wan37.logic.service.cache.UserServiceCache;
import com.wan37.logic.utils.DelayDequeThreadPollUtil;
import com.wan37.logic.utils.RouteUtils;
import com.wan37.protobuf.constant.Common;
import com.wan37.protobuf.constant.PtoNum;
import com.wan37.protobuf.message.client2server.game.Game;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : luoyong
 * @date : 2020-05-29 10:31
 **/
public class CGameMoveHandler extends MsgHandler {

    private static final Logger logger = LoggerFactory.getLogger(CGameMoveHandler.class);

    private SceneServiceCache sceneServiceCache;
    private RouteUtils routeUtils;
    private RoleServiceCache roleServiceCache;
    private UserServiceCache userServiceCache;
    private DelayDequeThreadPollUtil delayDequeThreadPollUtil;
    private LogicWorkerHandlerCenter logicWorkerHandlerCenter;

    /**
     * MsgHandler构造函数
     *
     * @param messageVO
     */
    public CGameMoveHandler(MessageVO messageVO) {
        super(messageVO);
        this.sceneServiceCache = SpringContextHolder.getBean("sceneServiceCache");
        this.routeUtils = SpringContextHolder.getBean("routeUtils");
        this.roleServiceCache = SpringContextHolder.getBean("roleServiceCache");
        this.userServiceCache = SpringContextHolder.getBean("userServiceCache");
        this.delayDequeThreadPollUtil = SpringContextHolder.getBean("delayDequeThreadPollUtil");
        this.logicWorkerHandlerCenter = SpringContextHolder.getBean("logicWorkerHandlerCenter");
    }

    @Override
    public void execute(Worker worker) throws Exception {
        Game.CGameMove cGameMove = (Game.CGameMove) messageVO.getMessage();

        String userId = cGameMove.getSenderId();

        String currentScene = cGameMove.getCurrentScene();

        String nextScene = cGameMove.getNextScene();

        if (!isScene(nextScene)) {
            logger.info("{userId}:" + userId + "将要切换的场景不存在,切换场景失败！！！");
            routeUtils.sendResponse(Common.GAME_MOVE_ERROR,
                    currentScene, messageVO.getNetId(), userId);
            return;
        }

        if (!sceneServiceCache.sceneNameToIdMap.containsKey(currentScene)) {
            routeUtils.sendResponse(Common.GAME_MOVE_ERROR,
                    currentScene, messageVO.getNetId(), userId);
            return;
        }
        String currentSceneId = sceneServiceCache.sceneNameToIdMap.get(currentScene);
        String nextSceneId = sceneServiceCache.sceneNameToIdMap.get(nextScene);

        if (sceneServiceCache.getSceneServiceMap().containsKey(currentSceneId)) {
            if (sceneServiceCache.getSceneServiceMap().get(currentSceneId).getGoSceneIdSet().contains(nextSceneId)) {

                logger.info("{userId}:" + userId + "允许切换场景！");

                //转移场景逻辑
                move(currentSceneId, nextSceneId, userId, nextScene);

            } else {
                logger.info("{userId}:" + userId + "不允许切换下一个场景,切换场景失败！！！");
                routeUtils.sendResponse(Common.GAME_MOVE_ERROR,
                        currentScene, messageVO.getNetId(), userId);
            }
        }
    }

    public void move(String currentSceneId, String nextSceneId, String userId, String nextScene) throws IllegalAccessException, InstantiationException, InvocationTargetException {
        //用户离开场景，从集合中移除，需要推送自己给当前场景的其他用户自己离开，让他们删除数据
        sceneServiceCache.getSceneServiceMap().get(currentSceneId).getUserIdSet().remove(userId);
        for (String userId1 : sceneServiceCache.getSceneServiceMap().get(currentSceneId).getUserIdSet()){
            routeUtils.sendResponse(Common.OTHER_USER_MOVE, userId, 0, userId1);
        }

        //用户添加进新场景集合
        sceneServiceCache.getSceneServiceMap().get(nextSceneId).getUserIdSet().add(userId);

        /**
         * 获取到用户角色，移除旧场景中集合的实体，添加新场景中实体集合中
         */
        UserServiceCache.User user = userServiceCache.getUserServiceMap().get(userId);
        user.setSceneId(nextSceneId);
        List<String> roleVOIdList = user.getRoleIdList();

        //改变用户当前所在场景
        user.setSceneId(nextSceneId);

        /**
         * 进行自动回复hp的设置
         */
        for (String roleId : roleVOIdList) {
            logger.info(roleId + "hp自动回复已启动！！！！");
            delayDequeThreadPollUtil.stop(delayDequeThreadPollUtil.getScheduledFutureMapKey(roleId, AutoAddHpHandler.class.getSimpleName()));
            delayDequeThreadPollUtil.updateTimeWithFixedDelay(60, 60, roleId, nextSceneId, new AutoAddHpHandler(roleId));
        }

        CGameAoiHandler cGameAoiHandler = (CGameAoiHandler) HandlerManager.getMsgHandler
                (PtoNum.CGAMEAOI, userId, messageVO.getNetId(), null, messageVO.getCtx());
        cGameAoiHandler.getAllRole(userId, nextSceneId);
        //给客户端发送允许移动的消息
        routeUtils.sendResponse(Common.GAME_MOVE_SUCCESS,
                nextScene, messageVO.getNetId(), userId);

        //判断是临时场景的
        if (sceneServiceCache.getSceneServiceMap().get(currentSceneId).getLabel() == 1) {
            //销毁场景
            logicWorkerHandlerCenter.distributeWork(currentSceneId, new DestroySceneHandler(currentSceneId));
        }
    }

    private boolean isScene(String nextScene) {
        if (nextScene != null) {
            return sceneServiceCache.sceneSet.contains(nextScene);
        } else {
            return false;
        }
    }
}
